<?php

namespace App\Exceptions;

use App\Utils\Enums\ExceptionEnums;
use App\Utils\Helpers\Jump;
use Exception;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Validation\ValidationException;

class Handler extends ExceptionHandler
{

    use Jump;
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param \Exception $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        parent::report($exception);
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @param Exception $exception
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\JsonResponse|\Illuminate\View\View|\Symfony\Component\HttpFoundation\Response
     * @throws Exception
     */
    public function render($request, Exception $exception)
    {
        $code = $exception->getCode();
        $msg = $exception->getMessage();
        $httpStatus = isset(ExceptionEnums::HTTP_CODE_LIST[$code]) ? ExceptionEnums::HTTP_CODE_LIST[$code] : $exception->getHttpStatus(); // 得到对应的http状态码
        //  只处理自定义的APIException异常
        if ($exception instanceof InterException) {
            $data = $exception->getData();
            return $this->error($msg, $data, $code, $httpStatus);
        }  else if ($exception instanceof ValidationException) {
            return $this->error("验证异常: " . $exception->validator->errors()->first(), [],ExceptionEnums::PARAM_ERROR);
        } else if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
            return  $this->unauthenticated($request, $exception);
//            return $this->error($exception->getMessage() .'，请先登录！', [], ExceptionEnums::UN_AUTH);
        } else if ($exception instanceof \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken) {
            return $this->setIsSystemError(true)->error('CSRF-TOKEN验证失败!' . $exception->getMessage(), [], ExceptionEnums::UNKNOWN_ERROR);
        } else if ($exception instanceof QueryException) {
            return $this->setIsSystemError(true)->error('系统错误，请稍后再试！' . $exception->getMessage(), [], ExceptionEnums::UNKNOWN_ERROR);
        }

        return parent::render($request, $exception);
    }

    /**
     * Convert an authentication exception into a response.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Illuminate\Auth\AuthenticationException $exception
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
     */
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        $guards = $exception->guards();
        $url = '/';
        if (array_search('admin', $guards) !== false) {
            $url = route('admin::login.show');
        } elseif (array_search('member', $guards) !== false) {
            $url = route('member::login.show');
        }

        return $request->expectsJson()
            ? response()->json(['message' => $exception->getMessage()], 401)
            : redirect()->guest($url);
    }
}
